package com.rhcloud.insongr.srv.wechat.servlet;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.Writer;
import java.net.MalformedURLException;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Properties;
import java.util.Scanner;
import java.util.logging.Logger;

import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.DataSource;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import net.xeoh.plugins.base.PluginManager;
import net.xeoh.plugins.base.impl.PluginManagerFactory;
import cn.ekuma.epos.bean.util.ProductInfoHelper;
import cn.ekuma.epos.businesslogic.ProductUtil;
import cn.ekuma.epos.datalogic.define.DataLogicERP;
import cn.ekuma.epos.remote.service.PoolSession;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import com.openbravo.bean.Product;
import com.openbravo.data.basic.BasicException;
import com.openbravo.data.loader.I_Session;
import com.rhcloud.insongr.srv.wechat.bean.WeChatReqBean;
import com.rhcloud.insongr.srv.wechat.bean.WeChatRespBean;
import com.rhcloud.insongr.srv.wechat.common.Constants;
import com.rhcloud.insongr.srv.wechat.common.Sha1Util;
import com.sun.xml.bind.marshaller.CharacterEscapeHandler;

public class WeChatServlet extends HttpServlet {
	private static final long serialVersionUID = -2776902810130266533L;
	private static Logger log = Logger.getLogger(WeChatServlet.class.getName());

	DataLogicERP dataLogic;
	
	protected final PluginManager pmf = PluginManagerFactory.createPluginManager();
	
	@Override
	public void init(ServletConfig config) throws ServletException {
		//pmf.addPluginsFrom(new File("plugins/").toURI());
		try {
			dataLogic=new DataLogicERP(getSession(config));
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
        super.init(config);
	}
	
	
	// 自定义 token
    private String TOKEN = "wechat";
 
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException {
        // 微信加密签名
        String signature = request.getParameter("signature");
        // 随机字符串
        String echostr = request.getParameter("echostr");
        // 时间戳
        String timestamp = request.getParameter("timestamp");
        // 随机数
        String nonce = request.getParameter("nonce");
 
        //String[] str = { TOKEN, timestamp, nonce };
        //Arrays.sort(str); // 字典序排序
        // String bigStr = str[0] + str[1] + str[2];
        
        String array[] = { TOKEN, timestamp, nonce };        
        Arrays.sort(array);//php demo排序 
        
        String str = "";//php demo转换字符串        
        for (int i = 0; i < array.length; i++) {   
        	str += array[i];      
        	}         
        String encode = Sha1Util.sha1(str); 
        
        
        // SHA1加密
        //String digest = new SHA1().getDigestOfString(bigStr.getBytes()).toLowerCase();
 
        // 确认请求来至微信
        if (encode.equals(signature)) {
            response.getWriter().print(echostr);
        }
    }

	
	
	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp)
			throws ServletException, IOException {
		Scanner scanner = new Scanner(req.getInputStream());
		resp.setContentType("application/xml");
		resp.setCharacterEncoding("UTF-8");
		PrintWriter out = resp.getWriter();
		try {
			// 1、获取用户发送的信息
			StringBuffer sb = new StringBuffer(100);
			while (scanner.hasNextLine()) {
				sb.append(scanner.nextLine());
			}
			
			// 2、解析用户的信息
			JAXBContext jc = JAXBContext.newInstance(WeChatReqBean.class);
			Unmarshaller u = jc.createUnmarshaller();
			WeChatReqBean reqBean = (WeChatReqBean) u.unmarshal(new StringReader(sb.toString()));
			
			// 3、判定用户是否发的是地理位置的PO，并查询天气
			String content = getContent(reqBean);
			
			// 4、创建一个回复消息
			jc = JAXBContext.newInstance(WeChatRespBean.class);
			Marshaller m = jc.createMarshaller();
			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
			m.setProperty(CharacterEscapeHandler.class.getName(), new CharacterEscapeHandler() {
				
				public void escape(char[] arg0, int arg1, int arg2, boolean arg3,
						Writer arg4) throws IOException {
					arg4.write(arg0, arg1, arg2);
				}
			});
			m.setProperty(Marshaller.JAXB_FRAGMENT, Boolean.TRUE);
			WeChatRespBean respBean = createRespBean(reqBean, content);
			m.marshal(respBean, out);
			out.flush();
		} catch (JAXBException e) {
			log.info(e.getMessage());
		} finally {
			if (scanner != null) {
				scanner.close();
				scanner = null;
			}
			if (out != null) {
				out.close();
				out = null;
			}
		}
	}

	/**
	 * @param reqBean
	 * @param content
	 * @return
	 */
	private WeChatRespBean createRespBean(WeChatReqBean reqBean, String content) {
		WeChatRespBean respBean = new WeChatRespBean();
		respBean.setFromUserName(reqBean.getToUserName());
		respBean.setToUserName(reqBean.getFromUserName());
		respBean.setMsgType("text");
		respBean.setCreateTime(new Date().getTime());
		respBean.setContent(content);
		return respBean;
	}

	/**　
	 * @param reqBean
	 * @throws JAXBException
	 * @throws MalformedURLException
	 */
	private String getContent(WeChatReqBean reqBean) throws JAXBException, MalformedURLException {
		StringBuffer content = new StringBuffer("亲，");
		String msgType=reqBean.getMsgType();
		if( Constants.MSGTYPE_TEXT.equalsIgnoreCase(msgType)){
			String codeOrReference=reqBean.getContent();
			if ("Hello2BizUser".equals(reqBean.getContent())) {
				// 这是新用户关注时默认发的一条信息。可以做一个欢迎处理。
				content.append("小Ｍ欢迎你的光临，现功能你可以输入商品编号（如81320264）或条码（6947503771065）来进行查询操作。[愉快]，更多操作可使用安卓客户端,clundpos.jd-app.com下载");
			} else{
				List<Product> listProducts=null;
				try {
					listProducts=ProductUtil.getProductInfo(dataLogic,codeOrReference);
				} catch (BasicException e) {
					e.printStackTrace();
					return e.getMessage();
				}
				if(!listProducts.isEmpty())
					for(Product p:listProducts){
						content.append(ProductInfoHelper.getProductDetial(p));
					}
				else
					content.append("对应的商品还没收入呢！");
			}
		} else if( Constants.MSGTYPE_IMAGE.equalsIgnoreCase(msgType))
			content.append("好漂亮的图片。[色]");	
		else
			content.append("想查商品，请给我发一个条码。");
			 
		
		return content.toString();
	}

	protected I_Session getSession(ServletConfig config) throws SQLException{
		PoolSession poolSession=(PoolSession) config.getServletContext().getAttribute("poolsession");
		if(poolSession!=null){
			System.out.println("find PoolSession in context:"+Thread.currentThread().getName());
			return poolSession;
		}
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			throw new SQLException(e);
		}
		
		Properties ps = new Properties();
		try {
			ps.load(PoolSession.class.getClassLoader().getResourceAsStream("DBProperties.properties"));
		} catch (FileNotFoundException e) {
			
			e.printStackTrace();
		} catch (IOException e) {
			
			e.printStackTrace();
		}
		DataSource dataSource = null;
		//�������Դ
		try {
			 dataSource = DruidDataSourceFactory.createDataSource(ps);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		poolSession=new PoolSession(dataSource);
		config.getServletContext().setAttribute("poolsession", poolSession);
		System.out.println("create new PoolSession in context:"+Thread.currentThread().getName());
		return poolSession;
	}
}
